package com.chinamobile.iot.extend.auth.imp;

import com.chinamobile.iot.extend.auth.IMqttAuthRestClient;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import javax.net.ssl.SSLContext;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;

@Component
@ConditionalOnExpression("${mqtt.anonymous}==false ")
public class MqttAuthRestClient implements IMqttAuthRestClient {

    @Autowired
    private RestTemplate restTemplate;

    public void setRestTemplate(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    @Value("&{mqtt.authAddress}")
    private String authAddress;

    public void setAuthAddress(String authAddress) {
        this.authAddress = authAddress;
    }

    @Bean
    public RestTemplate restTemplate() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
        TrustStrategy acceptingTrustStrategy = (x509Certificates, s) -> true;

        SSLContext sslContext = org.apache.http.ssl.SSLContexts.custom()
                .loadTrustMaterial(null, acceptingTrustStrategy)
                .build();

        SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext, (s, sslSession) -> true);

        CloseableHttpClient httpClient = HttpClients.custom()
                .setSSLSocketFactory(csf)
                .build();

        HttpComponentsClientHttpRequestFactory requestFactory =
                new HttpComponentsClientHttpRequestFactory();

        requestFactory.setHttpClient(httpClient);
        RestTemplate restTemplate = new RestTemplate(requestFactory);
        return restTemplate;
    }


    @Override
    public String checkPassword(String appToken, String loginName, String password) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.add("app-token", appToken);
        HttpEntity<String> requestEntity = new HttpEntity<>(null, httpHeaders);
        String url = "https://" + authAddress + "/rest-mqtt-auth/user/login?loginName={loginName}&password={password}";
        ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class, loginName, password);
        return responseEntity.getBody();
    }

    @Override
    public boolean deviceAlarmPermission(String deviceId, String alarmConfigName, String mqttId) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.add("mqttId", mqttId);
        HttpEntity<String> requestEntity = new HttpEntity<>(null, httpHeaders);
        String url = "https://" + authAddress + "/rest-mqtt-auth/topic/deviceAlarm?deviceId={deviceId} & alarmConfigName={alarmConfigName}";
        ResponseEntity<Boolean> responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, Boolean.class, deviceId, alarmConfigName);
        return responseEntity.getBody();
    }

    @Override
    public boolean deviceDataPermission(String deviceId, String dataName, String fieldName, String mqttId) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.add("mqttId", mqttId);
        HttpEntity<String> requestEntity = new HttpEntity<>(null, httpHeaders);
        String url = "https://" + authAddress + "/rest-mqtt-auth/topic/deviceData?deviceId={deviceId}&dataName={dataName}&fieldName={fieldName}";
        ResponseEntity<Boolean> responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, Boolean.class, deviceId, dataName, fieldName);
        return responseEntity.getBody();
    }

    @Override
    public boolean deviceStatPermission(String deviceId, String statName, String fieldName, String mqttId) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.add("mqttId", mqttId);
        HttpEntity<String> requestEntity = new HttpEntity<>(null, httpHeaders);
        String url = "https://" + authAddress + "/rest-mqtt-auth/topic/deviceStat?deviceId={deviceId}&statName={statName}&fieldName={fieldName}";
        ResponseEntity<Boolean> responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, Boolean.class, deviceId, statName, fieldName);
        return responseEntity.getBody();
    }

    @Override
    public boolean deviceStatePermission(String deviceId, String mqttId) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.add("mqttId", mqttId);
        HttpEntity<String> requestEntity = new HttpEntity<>(null, httpHeaders);
        String url = "https://" + authAddress + "/rest-mqtt-auth/topic/deviceState?deviceId={deviceId}";
        ResponseEntity<Boolean> responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, Boolean.class, deviceId);
        return responseEntity.getBody();
    }

    @Override
    public boolean alarmPermission(String alarmConfigName, String mqttId) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.add("mqttId", mqttId);
        HttpEntity<String> requestEntity = new HttpEntity<>(null, httpHeaders);
        String url = "https://" + authAddress + "/rest-mqtt-auth/topic/alarm?alarmConfigName={alarmConfigName}";
        ResponseEntity<Boolean> responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, Boolean.class, alarmConfigName);
        return responseEntity.getBody();
    }

    @Override
    public boolean statPermission(String statName, String fieldName, String mqttId) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.add("mqttId", mqttId);
        HttpEntity<String> requestEntity = new HttpEntity<>(null, httpHeaders);
        String url = "https://" + authAddress + "/rest-mqtt-auth/topic/stat?&statName={statName}&fieldName={fieldName}";
        ResponseEntity<Boolean> responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, Boolean.class, statName, fieldName);
        return responseEntity.getBody();
    }

}
